Skip to content

Recover module added - #101

Closed
Omesh2004 wants to merge 8 commits into
zhravan:mainfrom
Omesh2004:omesh_branch
Closed

Recover module added#101
Omesh2004 wants to merge 8 commits into
zhravan:mainfrom
Omesh2004:omesh_branch

Conversation

@Omesh2004

@Omesh2004 Omesh2004 commented Oct 1, 2025

Copy link
Copy Markdown
Contributor

Summary

Describe the change and its motivation.

i have added excercise related to recover exercise template

image Paste before/after where helpful.

Related issues

Fixes #

Summary by CodeRabbit

  • New Features

    • Added “Epoch Conversion” exercise (Beginner) covering time and Unix epoch conversion with guided hints.
    • Added “Safe Panic Recovery” exercise (Medium) focusing on recover/defer patterns with structured hints.
  • Tests

    • Introduced tests validating non-panicking and panicking scenarios for the panic recovery exercise, including verification of recovered values.

@coderabbitai

coderabbitai Bot commented Oct 1, 2025

Copy link
Copy Markdown

Walkthrough

Adds two exercises to the catalog: 36_epoch and 37_recover. Introduces template and tests for 37_recover, plus a reference solution. Updates epoch template test file with an incomplete function. No other files modified.

Changes

Cohort / File(s) Summary
Catalog updates
internal/exercises/catalog.yaml
Adds two project entries: 36_epoch (Beginner; time/epoch/unix) and 37_recover (Medium; builtins) with hints.
Recover exercise — template and tests
internal/exercises/templates/37_recover/recover.go, internal/exercises/templates/37_recover/recover_test.go
Adds DoWork (panics on negative input) and a stub Run using defer/recover pattern; introduces tests for no-panic and panic cases validating recovered value.
Recover exercise — solution
internal/exercises/solutions/37_recover/recover.go
Provides implementation of Run with deferred recover capturing panic from DoWork and returning the recovered value.
Epoch exercise — template test
internal/exercises/templates/36_epoch/epoch_test.go
Removes closing brace from TestTimeToEpoch, leaving the function incomplete (syntax error).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Tester
  participant Run as recover_exercise.Run
  participant DoWork as recover_exercise.DoWork

  Tester->>Run: Run(n)
  Note over Run: defer func(){ v = recover() }()
  Run->>DoWork: DoWork(n)
  alt n < 0
    DoWork-->>DoWork: panic("input cannot be negative")
    Note over Run: deferred recover() captures panic
    Run-->>Tester: recoveredValue = "input cannot be negative"
  else n ≥ 0
    DoWork-->>Run: return
    Run-->>Tester: recoveredValue = nil
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • added epoch #89 — Modifies the same 36_epoch exercise area (catalog and exercise assets), indicating direct overlap.

Suggested labels

enhancement, good first issue, beginners, goodfirstissue, feat

Suggested reviewers

  • zhravan

Poem

Thump-thump goes my curious paw,
I catch your panics with gentle awe.
Time ticks from epoch’s nest,
Recover wraps each startled test.
Hop, compile—well, almost there—
Mind that brace, handle with care! 🐇⌛️

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title “Recover module added” correctly identifies that a recover exercise was introduced but does not mention the newly added epoch conversion exercise, making it only partially representative of the full scope of changes.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between db5cfa4 and 2d07529.

📒 Files selected for processing (2)
  • internal/exercises/catalog.yaml (1 hunks)
  • internal/exercises/templates/36_epoch/epoch_test.go (0 hunks)
💤 Files with no reviewable changes (1)
  • internal/exercises/templates/36_epoch/epoch_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • internal/exercises/catalog.yaml

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
internal/exercises/solutions/36_epoch/epoch.go (1)

57-69: Simplify the UnixSeconds map entry.

Lines 60-61 create a redundant string with duplicate formatted times. The expression time.Unix(now.Unix(), 0).Format(...) on line 60 produces the same result as time.Unix(now.Unix(), 0).UTC().Format(...) on line 61 (since time.Unix already returns UTC time). This concatenation pattern is unclear and doesn't add value.

Consider simplifying to:

 	return map[string]string{
-		"UnixSeconds":      time.Unix(now.Unix(), 0).Format("2006-01-02 15:04:05") + " (epoch: " + 
-		                    time.Unix(now.Unix(), 0).UTC().Format("2006-01-02 15:04:05") + ")",
+		"UnixSeconds":      time.Unix(now.Unix(), 0).UTC().Format("2006-01-02 15:04:05"),
 		"UnixSecondsRaw":   time.Unix(now.Unix(), 0).UTC().Format("2006-01-02 15:04:05"),

Or clarify the intended distinction between "UnixSeconds" and "UnixSecondsRaw".

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b99da22 and db5cfa4.

📒 Files selected for processing (7)
  • internal/exercises/catalog.yaml (1 hunks)
  • internal/exercises/solutions/36_epoch/epoch.go (1 hunks)
  • internal/exercises/solutions/37_recover/recover.go (1 hunks)
  • internal/exercises/templates/36_epoch/epoch.go (1 hunks)
  • internal/exercises/templates/36_epoch/epoch_test.go (1 hunks)
  • internal/exercises/templates/37_recover/recover.go (1 hunks)
  • internal/exercises/templates/37_recover/recover_test.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (4)
internal/exercises/templates/37_recover/recover_test.go (2)
internal/exercises/solutions/37_recover/recover.go (1)
  • Run (14-30)
internal/exercises/templates/37_recover/recover.go (1)
  • Run (15-25)
internal/exercises/solutions/37_recover/recover.go (1)
internal/exercises/templates/37_recover/recover.go (2)
  • DoWork (4-10)
  • Run (15-25)
internal/exercises/templates/36_epoch/epoch_test.go (1)
internal/exercises/templates/36_epoch/epoch.go (2)
  • EpochToTime (6-9)
  • TimeToEpoch (12-15)
internal/exercises/templates/37_recover/recover.go (1)
internal/exercises/solutions/37_recover/recover.go (2)
  • DoWork (4-10)
  • Run (14-30)
🔇 Additional comments (13)
internal/exercises/templates/37_recover/recover_test.go (2)

7-13: LGTM!

The test correctly verifies that Run(10) does not panic and returns nil, validating the non-panic code path.


15-28: LGTM!

The test properly verifies panic recovery behavior, including type assertion with safety checks and validation of the expected panic message.

internal/exercises/templates/37_recover/recover.go (2)

3-10: LGTM!

The DoWork function correctly demonstrates a panic scenario with a clear error message. The implementation aligns with test expectations and the solution.


12-25: LGTM!

The template structure is well-designed for teaching defer/recover patterns. The named return value and instructional comments provide clear guidance for learners to implement the recovery logic.

internal/exercises/templates/36_epoch/epoch.go (1)

3-15: LGTM!

The template functions are well-documented with clear format specifications. The intentionally incorrect implementations serve the exercise's learning objectives effectively.

internal/exercises/solutions/37_recover/recover.go (2)

3-10: LGTM!

The DoWork implementation is correct and consistent with the template and test expectations.


12-30: LGTM!

The defer/recover implementation is textbook-correct and demonstrates proper panic recovery patterns. The educational comments effectively explain each step of the recovery mechanism.

internal/exercises/templates/36_epoch/epoch_test.go (1)

5-20: Approve symmetric epoch/time conversion tests. Epoch timestamp 1633046400 correctly maps to 2021-10-01 00:00:00 UTC.

internal/exercises/catalog.yaml (1)

180-188: LGTM! Well-structured epoch exercise entry.

The catalog entry is well-defined with appropriate difficulty, topics, and helpful hints that guide learners through epoch conversion concepts.

internal/exercises/solutions/36_epoch/epoch.go (4)

10-22: LGTM! Current time getters are correctly implemented.

All three functions properly use time.Now() and the appropriate conversion methods. The millisecond conversion correctly divides UnixNano() by the millisecond duration constant.


26-34: LGTM! Formatted time functions are correct.

Both functions properly format the current UTC time with appropriate precision levels (microsecond and second).


40-43: LGTM! Clean epoch-to-time conversion.

The function correctly uses time.Unix() for conversion and formats the result in UTC.


47-53: Verify error handling for parse failures.

The function silently returns 0 when parsing fails. For an educational exercise solution, this might confuse learners who pass invalid input. Consider whether returning an error or panicking would better demonstrate proper error handling patterns.

However, if this silent failure is intentional for the exercise design (e.g., tests expect 0 for invalid input), then the current implementation is acceptable.

Do you want the solution to demonstrate explicit error handling, or is returning 0 the intended behavior for this exercise?

Comment thread internal/exercises/catalog.yaml Outdated
Comment on lines +72 to +74
func formatInt(val int64) string {
return time.Unix(0, val).UTC().Format("2006-01-02 15:04:05")
} No newline at end of file

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Critical: formatInt incorrectly interprets input.

The formatInt helper calls time.Unix(0, val) which interprets val as nanoseconds (the second parameter). However, this function is called with:

  • now.Unix() (line 63) - which is in seconds
  • now.UnixMilli() (line 64) - which is in milliseconds
  • now.UnixNano() (line 65) - which is in nanoseconds (only this is correct)

This will produce incorrect dates for all callers except UnixNanoseconds.

The correct implementation should be:

-// Helper: format int64 as string
-func formatInt(val int64) string {
-	return time.Unix(0, val).UTC().Format("2006-01-02 15:04:05")
-}
+// Helper: format unix timestamp (seconds) as string
+func formatSeconds(val int64) string {
+	return time.Unix(val, 0).UTC().Format("2006-01-02 15:04:05")
+}
+
+// Helper: format unix timestamp (milliseconds) as string
+func formatMillis(val int64) string {
+	return time.Unix(0, val*int64(time.Millisecond)).UTC().Format("2006-01-02 15:04:05")
+}
+
+// Helper: format unix timestamp (nanoseconds) as string
+func formatNanos(val int64) string {
+	return time.Unix(0, val).UTC().Format("2006-01-02 15:04:05")
+}

And update the calls in NowFormats():

 	return map[string]string{
 		"UnixSeconds":      time.Unix(now.Unix(), 0).Format("2006-01-02 15:04:05") + " (epoch: " + 
 		                    time.Unix(now.Unix(), 0).UTC().Format("2006-01-02 15:04:05") + ")",
 		"UnixSecondsRaw":   time.Unix(now.Unix(), 0).UTC().Format("2006-01-02 15:04:05"),
-		"UnixSecondsInt":   formatInt(now.Unix()),
-		"UnixMilliseconds": formatInt(now.UnixMilli()),
-		"UnixNanoseconds":  formatInt(now.UnixNano()),
+		"UnixSecondsInt":   formatSeconds(now.Unix()),
+		"UnixMilliseconds": formatMillis(now.UnixMilli()),
+		"UnixNanoseconds":  formatNanos(now.UnixNano()),
 		"FormattedFull":    GetCurrentFormattedTime(),
 		"FormattedSimple":  GetCurrentFormattedTimeSimple(),
 	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func formatInt(val int64) string {
return time.Unix(0, val).UTC().Format("2006-01-02 15:04:05")
}
// --- Replace the old formatInt helper with three explicit functions ---
-// Helper: format int64 as string
-func formatInt(val int64) string {
- return time.Unix(0, val).UTC().Format("2006-01-02 15:04:05")
-}
// Helper: format unix timestamp (seconds) as string
func formatSeconds(val int64) string {
return time.Unix(val, 0).UTC().Format("2006-01-02 15:04:05")
}
// Helper: format unix timestamp (milliseconds) as string
func formatMillis(val int64) string {
// time.Millisecond is a time.Duration (in nanoseconds)
return time.Unix(0, val*int64(time.Millisecond)).UTC().Format("2006-01-02 15:04:05")
}
// Helper: format unix timestamp (nanoseconds) as string
func formatNanos(val int64) string {
return time.Unix(0, val).UTC().Format("2006-01-02 15:04:05")
}
// --- And in NowFormats(), update the calls: ---
return map[string]string{
"UnixSeconds": time.Unix(now.Unix(), 0).Format("2006-01-02 15:04:05") +
" (epoch: " + time.Unix(now.Unix(), 0).UTC().Format("2006-01-02 15:04:05") + ")",
"UnixSecondsRaw": time.Unix(now.Unix(), 0).UTC().Format("2006-01-02 15:04:05"),
- "UnixSecondsInt": formatInt(now.Unix()),
- "UnixMilliseconds": formatInt(now.UnixMilli()),
"UnixSecondsInt": formatSeconds(now.Unix()),
"UnixMilliseconds": formatMillis(now.UnixMilli()),
"UnixNanoseconds": formatNanos(now.UnixNano()),
"FormattedFull": GetCurrentFormattedTime(),
"FormattedSimple": GetCurrentFormattedTimeSimple(),
}
🤖 Prompt for AI Agents
internal/exercises/solutions/36_epoch/epoch.go lines 72-74: formatInt currently
treats its int64 input as nanoseconds (time.Unix(0, val)) which is wrong for
callers passing seconds and milliseconds; change the implementation to convert
the input correctly based on units (use time.Unix(val, 0) for seconds,
time.Unix(val/1e3, (val%1e3)*1e6) for milliseconds, and time.Unix(0, val) for
nanoseconds) and update NowFormats() calls so each call passes the correct form
(or call separate helper functions) — ensure the logged/returned formatted time
uses the corrected conversion and UTC formatting.

@Omesh2004

Copy link
Copy Markdown
Contributor Author

can u check once now

@zhravan

zhravan commented Oct 1, 2025

Copy link
Copy Markdown
Owner

@Omesh2004 : Can you resolve the conflicts in the mean time please?

@zhravan zhravan left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Omesh2004 : Can you take latest pull and resolve the conflicts and raise final PR? Thank you so much for the efforts!

@Omesh2004 Omesh2004 closed this Oct 2, 2025
@Omesh2004
Omesh2004 deleted the omesh_branch branch October 2, 2025 05:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants